// utils/request.ts
import Taro from "@tarojs/taro";
import { getToken, removeToken, isAuthenticated, removeUserInfo } from "./auth";
const whitePaths = ["/phoneLogin", "/sendCode"];
const env = Taro.getEnv();
export const BASE_URL = (function () {
  if (env === Taro.ENV_TYPE.WEAPP) {
    // return "http://cz.aliyun.zjczrj.com";
    // return 'https://soft.zjjxf.net/caizhengApi'
    // return "http://192.168.207.217:8080"
  }
  return "http://192.168.207.217:8080";
  // return "https://soft.zjjxf.net/caizhengApi"
  // return 'http://cz.aliyun.zjczrj.com'
})();
// 定义接口返回数据结构
interface IResponseData<T = any> {
  code: number;
  msg: string;
  data: T;
}

// 定义请求配置
interface IRequestOptions extends Taro.request.Option {
  loading?: boolean; // 是否显示加载提示
  loadingText?: string; // 加载提示文字
  auth?: boolean; // 是否需要认证
}

// 基础请求方法
const request = <T = any>(options: IRequestOptions): Promise<T> => {
  return new Promise((resolve, reject) => {
    const {
      url,
      method = "GET",
      data = {},
      header = {},
      loading = true,
      loadingText = "加载中...",
      auth = true,
    } = options;

    if (!isAuthenticated() && !whitePaths.includes(url)) {
      Taro.reLaunch({
        url: "/pages/login/index",
      });
    }

    // 显示加载提示
    if (loading) {
      Taro.showLoading({
        title: loadingText,
        mask: true,
      });
    }

    // 添加认证头
    if (auth) {
      const token = getToken();
      if (token) {
        header["Authorization"] = `Bearer ${token}`;
      }
    }

    // 发起请求
    Taro.request({
      url: `${BASE_URL}${url}`,
      method,
      data,
      header,
      success: (res) => {
        if (loading) {
          Taro.hideLoading();
        }
        const { statusCode, data } = res;
        if (data.code === 401) {
          //用户没有权限了
          Taro.showToast({
            title: data.msg,
            icon: "none",
            duration: 2000,
          });
          removeToken();
          removeUserInfo();
          Taro.reLaunch({
            url: "/pages/login/index",
          });
          reject(res);
          return;
        }

        // 处理HTTP状态码
        if (statusCode !== 200) {
          handleError(res);
          reject(res);
          return;
        }

        // 处理业务状态码
        const response = data as IResponseData<T>;
        if (response.code !== 200) {
          handleBusinessError(response);
          reject(response);
          return;
        }

        resolve(response as any);
      },
      fail: (err) => {
        if (loading) {
          Taro.hideLoading();
        }
        handleError(err);
        reject(err);
      },
      complete: () => {
        // if (loading) {
        //   Taro.hideLoading();
        // }
      },
    });
  });
};

// 错误处理
const handleError = (error: any) => {
  let errorMessage = "请求失败";

  console.log(error);

  if (error.statusCode === 401) {
    errorMessage = "登录已过期，请重新登录";
    removeToken();
    // 跳转到登录页
    Taro.navigateTo({ url: "/pages/login/index" });
  } else if (error.statusCode === 404) {
    errorMessage = "请求资源不存在";
  } else if (error.statusCode >= 500) {
    errorMessage = "服务器错误";
  }

  Taro.showToast({
    title: errorMessage,
    icon: "none",
    duration: 2000,
  });
};

const handleBusinessError = (response: IResponseData) => {
  Taro.showToast({
    title: response.msg || "业务处理失败",
    icon: "none",
    duration: 2000,
  });

  // debugger
};

// 导出常用方法
export const get = <T = any>(
  url: string,
  data?: any,
  options?: Partial<IRequestOptions>
) => {
  return request<T>({ url, data, method: "GET", ...options });
};

export const post = <T = any>(
  url: string,
  data?: any,
  options?: Partial<IRequestOptions>
) => {
  return request<T>({ url, data, method: "POST", ...options });
};

export const put = <T = any>(
  url: string,
  data?: any,
  options?: Partial<IRequestOptions>
) => {
  return request<T>({ url, data, method: "PUT", ...options });
};

export const del = <T = any>(
  url: string,
  data?: any,
  options?: Partial<IRequestOptions>
) => {
  return request<T>({ url, data, method: "DELETE", ...options });
};

export default {
  get,
  post,
  put,
  del,
};
